#pragma once

#include <CFNetwork/CFNetwork.h>
#include <json/json.h>
#ifndef _NO_LIB_
#pragma comment(lib, "CFNetwork.lib")
#endif

using namespace std;

enum WEBPARM_TYPE;

typedef struct
{
	bool bRet,bGetString; intptr_t statusCode;
	LPCSTR statusLine;
	LPCVOID respData; intptr_t respDataLength;
} respStruct;

typedef struct
{
	LPCSTR name, value;
} propertyStruct;

class CCFWeb
{
public:
	CCFWeb();
	~CCFWeb();
	static void done();
	static bool CheckMainThread();
	static LPCSTR cvCFString(CFStringRef string);

#ifndef _NOSERVER_
	intptr_t WebComm(WEBPARM_TYPE type, LPCSTR &data, intptr_t dataLen, bool doDecode = true);
#endif
	intptr_t DecodeResp(LPCSTR &respString);
	static bool parseJson(LPCSTR data, Json::Value &root);
	bool isMyStream(CFReadStreamRef stream){ return readStream && readStream == stream; }
	void ResponseEndEncountered(void* infoPtr);
	void ResponseErrorOccurred();

	LPCVOID WebRequest(LPCSTR sUrl, bool DoGet, intptr_t *pDataLength,
		CFDataRef bodyData, const propertyStruct *propertys, intptr_t propCount);
	LPCVOID WebGet(LPCSTR sUrl, intptr_t *pDataLength,
		CFDataRef bodyData = nullptr, const propertyStruct *propertys = nullptr, intptr_t propCount = 0);
	LPCVOID WebGet(LPCSTR sUrl, intptr_t *pDataLength, LPCSTR bodyString,
		const propertyStruct *propertys = nullptr, intptr_t propCount = 0);
	LPCVOID WebGet(LPCSTR sUrl, intptr_t *pDataLength, byte *bodyData, intptr_t bodyDataLength,
		const propertyStruct *propertys = nullptr, intptr_t propCount = 0);
	LPCVOID WebPost(LPCSTR sUrl, intptr_t *pDataLength,
		CFDataRef bodyData = nullptr, const propertyStruct *propertys = nullptr, intptr_t propCount = 0);
	LPCVOID WebPost(LPCSTR sUrl, intptr_t *pDataLength, LPCSTR bodyString,
		const propertyStruct *propertys = nullptr, intptr_t propCount = 0);
	LPCVOID WebPost(LPCSTR sUrl, intptr_t *pDataLength, byte *bodyData, intptr_t bodyDataLength,
		const propertyStruct *propertys = nullptr, intptr_t propCount = 0);

	CStatic *m_pInfo;
	bool needQQ;
protected:
	LPCSTR TypeName(WEBPARM_TYPE type);
	intptr_t DecodeResp_real(LPCSTR &respString);
	static bool parseJson_real(LPCSTR data, Json::Value &root);
	CFDataRef DataRef(LPCSTR str);
	CFDataRef DataRef(byte *data, intptr_t dataLength);

	CFReadStreamRef readStream;
	HANDLE hResp;
	respStruct resp;
};
